#ifndef _VIDEO_MEMORY_H_
#define _VIDEO_MEMORY_H_
#include "stdint.h"
#include <map>
#include <list>
#include <vector>

namespace video
{

using namespace::std;


class IRefBase
{
public:
    virtual ~IRefBase() {};
    virtual int32_t add_ref() = 0;
    virtual int32_t release() = 0;
};

class IMemoryMgr;
class IMemory : public IRefBase {

private:
    int32_t _refs;
    int32_t _type;
    uint8_t *_mem;
    uint32_t _size;
    IMemoryMgr *_obs;
    void *_obs_ctx;

public:
    IMemory( int32_t type );
    virtual ~IMemory();

    virtual bool allocate( uint8_t *addr, int32_t size );
    virtual bool deallocate();

    virtual uint8_t *ptr();
    virtual uint32_t size() const;
    virtual int32_t type() const;

    virtual int32_t add_ref();
    virtual int32_t release();

    virtual int32_t set_mgr( IMemoryMgr *mgr, void *ctx );
};



class Video_Frame : public IMemory
{
private:
    int32_t _timestamp;
    int32_t _w;
    int32_t _h;
    int32_t _w_stride;
    int32_t _h_stride;
    int32_t _type;
    int32_t caclu_size( int32_t type );
public:
    Video_Frame( int32_t type, int32_t ts, int32_t w, int32_t h, int32_t w_stride, int32_t h_stride );
    virtual ~Video_Frame() {}
    virtual bool allocate( uint8_t *addr, int32_t size );
    virtual bool deallocate();
    virtual int32_t set_timestamp( int32_t ts );
    virtual int32_t timestamp() const;
    uint8_t *memory();
};

class Buffer_Frame : public IMemory
{
private:
    int32_t _timestamp;
    int32_t _type;
    int32_t _size;
public:
    Buffer_Frame( int32_t type, int32_t ts, int32_t size );
    virtual ~Buffer_Frame() {}
    virtual bool allocate( uint8_t *addr, int32_t size );
    virtual bool deallocate();
    virtual int32_t set_timestamp( int32_t ts );
    virtual int32_t timestamp() const;
    uint8_t *memory();
};


class IMemoryMgr{

public:
    virtual ~IMemoryMgr() {};
    virtual void signal_mem_release( IMemory *mem, void *ctx ) = 0;

private:
    IMemoryMgr & operator=( const IMemoryMgr & );
};





} // namespace name

#endif